home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / sd-uss / sound.c next >
C/C++ Source or Header  |  1998-01-20  |  3KB  |  131 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Support for Linux/USS sound
  5.   * 
  6.   * Copyright 1997 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "memory.h"
  15. #include "custom.h"
  16. #include "audio.h"
  17. #include "gensound.h"
  18. #include "sounddep/sound.h"
  19. #include "events.h"
  20.  
  21. #include <sys/ioctl.h>
  22.  
  23. #ifdef HAVE_SYS_SOUNDCARD_H
  24. #include <sys/soundcard.h>
  25. #elif defined HAVE_MACHINE_SOUNDCARD_H
  26. #include <machine/soundcard.h>
  27. #else
  28. #error "Something went wrong during configuration."
  29. #endif
  30.  
  31. int sound_fd;
  32. static int have_sound;
  33. static unsigned long formats;
  34.  
  35. uae_u16 sndbuffer[44100];
  36. uae_u16 *sndbufpt;
  37. int sndbufsize;
  38.  
  39. static int exact_log2(int v)
  40. {
  41.     int l = 0;
  42.     while ((v >>= 1) != 0)
  43.     l++;
  44.     return l;
  45. }
  46.  
  47. void close_sound(void)
  48. {
  49.     if (have_sound)
  50.     close(sound_fd);
  51. }
  52.  
  53. int setup_sound(void)
  54. {
  55.     sound_fd = open ("/dev/dsp", O_WRONLY);
  56.     have_sound = !(sound_fd < 0);
  57.     if (!have_sound)
  58.     return 0;
  59.  
  60.     if (ioctl (sound_fd, SNDCTL_DSP_GETFMTS, &formats) == -1) {
  61.     fprintf(stderr, "ioctl failed - can't use sound.\n");
  62.     close(sound_fd);
  63.     have_sound = 0;
  64.     return 0;
  65.     }
  66.  
  67.     sound_available = 1;
  68.     return 1;
  69. }
  70.  
  71. int init_sound (void)
  72. {
  73.     int tmp;
  74.     int rate;
  75.     int dspbits;
  76.  
  77.     if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) {
  78.     fprintf(stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz);
  79.     currprefs.sound_maxbsiz = 8192;
  80.     }
  81.  
  82.     tmp = 0x00040000 + exact_log2(currprefs.sound_maxbsiz);
  83.     ioctl (sound_fd, SNDCTL_DSP_SETFRAGMENT, &tmp);
  84.     ioctl (sound_fd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
  85.  
  86.     dspbits = currprefs.sound_bits;
  87.     ioctl (sound_fd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
  88.     ioctl (sound_fd, SOUND_PCM_READ_BITS, &dspbits);
  89.     if (dspbits != currprefs.sound_bits) {
  90.     fprintf(stderr, "Can't use sound with %d bits\n", currprefs.sound_bits);
  91.     return 0;
  92.     }
  93.  
  94.     tmp = currprefs.stereo;
  95.     ioctl (sound_fd, SNDCTL_DSP_STEREO, &tmp);
  96.  
  97.     rate = currprefs.sound_freq;
  98.     ioctl (sound_fd, SNDCTL_DSP_SPEED, &rate);
  99.     ioctl (sound_fd, SOUND_PCM_READ_RATE, &rate);
  100.     /* Some soundcards have a bit of tolerance here. */
  101.     if (rate < currprefs.sound_freq * 90 / 100 || rate > currprefs.sound_freq * 110 / 100) {
  102.     fprintf(stderr, "Can't use sound with desired frequency %d\n", currprefs.sound_freq);
  103.     return 0;
  104.     }
  105.  
  106.     sample_evtime = (long)maxhpos * maxvpos * 50 / rate;
  107.  
  108.     if (dspbits == 16) {
  109.     /* Will this break horribly on bigendian machines? Possible... */
  110.     if (!(formats & AFMT_S16_LE))
  111.         return 0;
  112.     init_sound_table16 ();
  113.     eventtab[ev_sample].handler = currprefs.stereo ? sample16s_handler : sample16_handler;
  114.     } else {
  115.     if (!(formats & AFMT_U8))
  116.         return 0;
  117.     init_sound_table8 ();
  118.     eventtab[ev_sample].handler = currprefs.stereo ? sample8s_handler : sample8_handler;
  119.     }
  120.     sound_available = 1;
  121.     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
  122.         dspbits, rate, sndbufsize);
  123.     sndbufpt = sndbuffer;
  124.     
  125. #ifdef FRAME_RATE_HACK
  126.     vsynctime = vsynctime * 9 / 10;
  127. #endif    
  128.  
  129.     return 1;
  130. }
  131.